package com.sesame.basic.controller;

import com.sesame.basic.ProjectConfig;
import com.sesame.sso.cache.SsoCacheServer;
import com.sesame.sso.cache.WebUserCache;
import com.sesame.sso.menu.bean.SsoMenu;
import com.sesame.sso.menu.service.SsoMenuService;
import com.sesame.sso.role.bean.SsoRole;
import com.sesame.sso.user.bean.SsoUser;
import com.sesame.sso.user.service.SsoUserService;
import kim.sesame.framework.entity.GMap;
import kim.sesame.framework.utils.Argument;
import kim.sesame.framework.utils.GData;
import kim.sesame.framework.utils.MD5Util;
import kim.sesame.framework.utils.StringUtil;
import kim.sesame.framework.web.annotation.IgnoreLoginCheck;
import kim.sesame.framework.web.cas.CasUtil;
import kim.sesame.framework.web.context.UserContext;
import kim.sesame.framework.web.controller.AbstractWebController;
import kim.sesame.framework.web.response.Response;
import kim.sesame.framework.web.response.ResponseFactory;
import lombok.Data;
import lombok.extern.apachecommons.CommonsLog;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户
 */
@CommonsLog
@RestController
@RequestMapping("/user")
public class UserController extends AbstractWebController {

    @Resource
    private SsoUserService ssoUserService;
    @Resource
    private WebUserCache webUserCache;
    @Autowired
    private SsoMenuService ssoMenuService;
    @Autowired
    SsoCacheServer ssoCacheServer;

    /**
     * 判断是否登录过
     *
     * @param request
     * @return
     */
    @IgnoreLoginCheck(isLoadUser = true)
    @RequestMapping("/verifyLogin")
    public Response verifyLogin(HttpServletRequest request, HttpServletResponse response) {
        String sessionId = CasUtil.getSessionId(request);
        SsoUser user = UserContext.getUserContext().getUser(SsoUser.class);
        GMap map = GMap.newMap();
        map.putAction("sessionId", sessionId);
        map.putAction("user", user);

        response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Credentials", "true");

        return returnSuccess(map);
    }

    /**
     * 登录
     */
    @IgnoreLoginCheck
    @RequestMapping("/login")
    public Response login(String account, String pwd, HttpServletRequest request, HttpServletResponse response) {
        Argument.notEmpty(account, "账号不能为空");
        Argument.notEmpty(pwd, "密码不能为空");

        SsoUser user = new SsoUser();
        user.setAccount(account);
        user.setPwd(MD5Util.encodeByMD5(pwd));
        user = ssoUserService.search(user);

        if (user == null) {
            return ResponseFactory.loginFailure("用户名或密码错误!");
        }
        if (!user.getIsEnable().equals(GData.BOOLEAN.YES)) {
            return ResponseFactory.loginFailure("你已被禁止登录,请联系管理员");
        }

        // 保存用户到缓存
        String sessionId = UserContext.getUserContext().getUserSessionId();

        if (StringUtil.isNotEmpty(sessionId)) {
            // 保存sessionid 到 cookie
            CasUtil.saveSessionIdToCookie(sessionId, response);

            // 添加用户信息到缓存
            webUserCache.addUsersToCache(user.getAccount(), sessionId);

            // 清除用户菜单缓存
            ssoCacheServer.queryMenuByUserCode_invalid(user.getAccount(), ProjectConfig.SysCode);
            // 清除用户角色缓存
            ssoCacheServer.queryRolesByUserno_invalid(user.getAccount());
            // 清除用户信息缓存
            ssoCacheServer.queryUserByAccount_invalid(user.getAccount());
        } else {
            return ResponseFactory.loginFailure("sessionId 获取错误");
        }

        return returnSuccess(sessionId);
    }

    /**
     * 修改密码
     */
    @RequestMapping("/updatepwd")
    public Response updatepwd(String pwd, String newPwd) {

        SsoUser user = UserContext.getUserContext().getUser(SsoUser.class);

        SsoUser bean = new SsoUser();
        bean.setAccount(user.getAccount());
        user = ssoUserService.search(bean);
        if (user.getPwd().equals(MD5Util.encodeByMD5(pwd))) {
            bean = new SsoUser();
            bean.setId(user.getId());
            bean.setPwd(MD5Util.encodeByMD5(newPwd));

            ssoUserService.update(bean);

            // 清除用户信息缓存
            ssoCacheServer.queryUserByAccount_invalid(user.getAccount());
            String sessionId = UserContext.getUserContext().getUserSessionId();

            //清除用户登录信息
            webUserCache.invalidUserCache(sessionId);

            return returnSuccess();
        } else {
            return ResponseFactory.loginFailure("原密码错误!");
        }
    }

    /**
     * 注销
     *
     * @return
     */
    @RequestMapping("/invalid")
    public Response invalid() {

        SsoUser user = UserContext.getUserContext().getUser(SsoUser.class);
        String sessionId = UserContext.getUserContext().getUserSessionId();

        ////清除用户登录信息
        webUserCache.invalidUserCache(sessionId);

        return returnSuccess();
    }

    /**
     * 获取登录的用户
     */
    @RequestMapping("/getUserInfo")
    public Response getUserInfo() {

        SsoUser user = UserContext.getUserContext().getUser(SsoUser.class);
        List<SsoRole> roles = UserContext.getUserContext().getUserRole(List.class);

        return returnSuccess(new UserInfo(user, roles));
    }

    @Data
    public class UserInfo implements java.io.Serializable {
        private SsoUser user;
        private List<SsoRole> roles;

        public UserInfo() {
        }

        public UserInfo(SsoUser user, List<SsoRole> roles) {
            this.user = user;
            this.roles = roles;
        }
    }

    /**
     * 返回所有权限的key的集合
     *
     * @return
     */
    @RequestMapping("/getAuthKeys")
    @ResponseBody
    public Response getAuthKeys(HttpServletRequest request) {

        List<String> list = getMenu().stream().map(SsoMenu::getAuthKey).collect(Collectors.toList());
        list.add("key_search");
        list.add("key_add");
        list.add("key_update");
        list.add("key_delete");

        return returnSuccess(list);
    }

    public List<SsoMenu> getMenu() {
        SsoUser user = UserContext.getUserContext().getUser(SsoUser.class);
        List<SsoMenu> list = ssoMenuService.getMenuByUserCode(user.getAccount(), ProjectConfig.SysCode);
        list.stream().forEach(bean -> {
            bean.setAuthKey(bean.getSystemCode() + "_" + bean.getCode());
        });
        return list;
    }

    /******************************************************************/
    //对外提供的接口
    @IgnoreLoginCheck
    @RequestMapping("/queryUserByAccount")
    public Response queryUserByAccount(String userNo) {
        SsoUser user = ssoCacheServer.queryUserByAccount(userNo);
        return returnSuccess(user);
    }

    @IgnoreLoginCheck
    @RequestMapping("/queryRolesByUserno")
    public Response queryRolesByUserno(String userNo) {
        List<SsoRole> list = ssoCacheServer.queryRolesByUserno(userNo);
        return returnSuccess(list);
    }

    @IgnoreLoginCheck
    @RequestMapping("/queryUserMenu")
    public Response queryUserMenu(String account, String systemCode, String basePath) {
        Argument.notEmpty(account, "用户账号 account 不能为空");
        Argument.notEmpty(systemCode, "系统编号 systemCode 不能为空");

        List<GMap> map = ssoMenuService.queryUserMenu(account, systemCode, basePath);

        return returnSuccess(map);
    }


}